package com.shire.shire_interface.service.kf;

import com.alibaba.druid.support.json.JSONUtils;
import com.shire.shire_interface.common.utils.JsonFormat;
import com.shire.shire_interface.common.utils.MD5;
import com.shire.shire_interface.common.utils.MathUtils;
import com.shire.shire_interface.common.utils.StrUtils;
import com.shire.shire_interface.constants.Constants;
import com.shire.shire_interface.constants.WxConstants;
import com.shire.shire_interface.constants.WxErrorCode;
import com.shire.shire_interface.controller.kf.WebSocketController;
import com.shire.shire_interface.model.command.WxCommand;
import com.shire.shire_interface.model.cs.WxChat;
import com.shire.shire_interface.model.friend.WxFriend;
import com.shire.shire_interface.model.friend.WxFriendExample;
import com.shire.shire_interface.model.friend.WxFriendLog;
import com.shire.shire_interface.model.group.WxGroup;
import com.shire.shire_interface.model.group.WxGroupExample;
import com.shire.shire_interface.model.user.WxAccount;
import com.shire.shire_interface.service.account.WxAccountService;
import com.shire.shire_interface.service.chat.WxChatService;
import com.shire.shire_interface.service.commandcenter.BaseCommandProcessor;
import com.shire.shire_interface.service.commandcenter.WxCommandService;
import com.shire.shire_interface.service.friend.WxFriendLogService;
import com.shire.shire_interface.service.friend.WxFriendService;
import com.shire.shire_interface.service.group.WxGroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.shire.shire_interface.common.utils.CMap.responseFailure;
import static com.shire.shire_interface.common.utils.CMap.responseSuccess;

@Service("kfService")
public class WebScoketService{

    private static Logger logger = LoggerFactory.getLogger(WebScoketService.class);

    private static final String _md5Key = "293#29ffwcc&^3IFS20a@$";

    @Resource
    private WxFriendService wxFriendService;
    @Resource
    private WxChatService wxChatService;
    @Resource
    private WxAccountService wxAccountService;
    @Resource
    private WxGroupService wxGroupService;
    @Resource
    private WxFriendLogService wxFriendLogService;
    @Resource
    private WxCommandService wxCommandService;
    @Resource
    private BaseCommandProcessor commandProcessor;

    private static WebScoketService instance;

    public static WebScoketService getInstance(){
        return instance;
    }

    @PostConstruct
    public void init(){
        instance = this;
    }

    public String getSecretCsId(String csId){
        return MD5.getMd5Str(_md5Key+csId);
    }

    public boolean checkSecretCsId(String csId, String key){
        return StrUtils.getNullStr(key).equals(getSecretCsId(csId));
    }

    public void receiveMessage(String sid, String message){
        try{
            Map<String, Object> map = JsonFormat.toMap(message);
            Integer opType = MathUtils.getMapIntValue(map, "opType", 0);
            Integer csId = StrUtils.getIntValue(sid, -1);
            Map<String, Object> rstMap = null;
            switch (opType){
                case 1: // 聊天信息
                    rstMap = sendChat(csId, map);
                    break;
                case 2: // 已读消息
                    setReadStatus(map);
                    break;
                case 3: // 添加群好友
                    rstMap = sendAddFriendFromGroup(csId, map);
                default:
                    break;
            }
            if(rstMap!=null){
                WebSocketController.sendMessage(sid, rstMap);
            }
        }
        catch (Exception e){
            logger.error("接收客服消息异常[message="+message+"]：", e);
        }
    }

    public Map<String, Object> setReadStatus(Map<String, Object> map){
        Integer chatId = (Integer)map.get("chatId");
        if(chatId==null || chatId==0){
            return responseFailure("chatId不存在!");
        }
        else{
            wxChatService.setChatReadStatus(chatId, Constants.YesNo.YES.ordinal());
        }
        return responseSuccess();
    }

    /**
     * 发送聊天信息
     * @param map
     * @return
     */
    private Map<String, Object> sendChat(Integer csId, Map<String, Object> map){
        String wxAccount = (String)map.get("wxAccount");
        String content = (String)map.get("content");
        Long msgId = Long.parseLong(map.get("msgId").toString());
        String friendId  = (String)map.getOrDefault("friendId",0);
        Integer msgType = (Integer) map.get("msgType");

        return sendFriendChat(csId, map, wxAccount, content, msgId, friendId, msgType);
    }


    private Map<String, Object> sendFriendChat(Integer csId, Map<String, Object> map, String wxAccount, String content, Long msgId, String friendId, Integer msgType) {
        WxFriend wxFriend = null;
        WxGroup wxGroup = null;

        boolean isGroup = friendId.endsWith("@chatroom");
        if (isGroup){
            WxGroupExample groupExample = new WxGroupExample();
            groupExample.createCriteria().andGroupnoEqualTo(friendId).andWxaccountEqualTo(wxAccount);
            List<WxGroup> wxGroups = wxGroupService.selectByExample(groupExample);
            if (wxGroups.size()==0){
                return responseFailure("好友不存在！");
            }
            wxGroup = wxGroups.get(0);
        }else {
            WxFriendExample friendExample = new WxFriendExample();
            friendExample.createCriteria().andWxaccountEqualTo(wxAccount).andFriendwxidEqualTo(friendId);
            List<WxFriend> wxFriends = wxFriendService.selectByExample(friendExample);
            if(wxFriends.size()==0){
                return responseFailure("好友不存在！");
            }
            wxFriend = wxFriends.get(0);
        }

        Integer chatId = (Integer) map.getOrDefault("id",0);
        WxChat chat = null;
        if(chatId>0){
            chat = wxChatService.selectByPrimaryKey(chatId);
            // 重发指令
            if(chat.getCmdid()==null){
                return responseFailure("发送指令不存在");
            }
            WxCommand wxCommand = wxCommandService.selectByPrimaryKey(chat.getCmdid());
            if(wxCommand.getRststatus()== WxErrorCode.SUCCESS){
                return responseFailure("该消息已成功发送");
            }
            wxCommand.setCmdstatus(WxConstants.CmdStatus.NEW.getCode());
            wxCommand.setRststatus(WxErrorCode.INIT_VALUE);
            wxCommand.setTrytimes(wxCommand.getTrytimes()+1);
            wxCommand.setUpdatetime(new Date());
            chat.setSendstatus(WxErrorCode.INIT_VALUE);
            wxCommandService.updateWxCommand(wxCommand);
            wxChatService.updateChat(chat);
            commandProcessor.addCommand(wxCommand.getCsid(),wxCommand.getAccountid(),wxCommand);
            Map<String, Object> rstMap = responseSuccess();

            rstMap.put("opType", 1);
            rstMap.put("chat", chat);
            rstMap.put("friendId", friendId);
            rstMap.put("msgId", msgId);
            return rstMap;
        }
        else {
            chat = new WxChat();
            chat.setWxaccount(wxAccount);
            chat.setMsgid(msgId.toString());
            if (isGroup){
                chat.setFriendwxid(wxGroup.getGroupno());
                chat.setFriendremark(wxGroup.getGroupname());
            }else {
                chat.setFriendwxid(wxFriend.getFriendwxid());
                chat.setFriendremark(wxFriend.getFriendnick());
            }

            chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
            chat.setContent(content);
            chat.setMsgtype(msgType);
            chat.setSendstatus(WxErrorCode.INIT_VALUE);
            chat.setReadstatus(Constants.YesNo.YES.ordinal());
            chat.setFromplat(0);
            chat.setShowstatus(Constants.YesNo.YES.getCode());
            chat.setCsid(csId);
            chat.setCreatetime(new Date());
            chat.setReadtime(new Date());
            Map<String, Object> rstMap = wxChatService.sendChatByCmd(chat);
            Boolean success = (Boolean) rstMap.get("success");
            if (success != null && success) {
                rstMap.put("opType", 1);
                rstMap.put("chat", chat);
                rstMap.put("friendId", friendId);
                rstMap.put("msgId", msgId);
            } else {
                rstMap.put("wxAccount", wxAccount);
                rstMap.put("friendId", friendId);
                rstMap.put("opType", 1);
                rstMap.put("msgId", msgId);
            }
            return rstMap;
        }
    }

    private Map<String, Object> sendAddFriendFromGroup(Integer csId, Map<String, Object> map){
        String memberWxId = (String)map.get("memberWxId");
        String memberNick = (String)map.get("memberNick");
        String groupNo = (String)map.get("groupNo");
        String wxAccount = (String)map.get("wxAccount");
        String applyMsg = StrUtils.getNullStr(map.get("applyMsg"));
        WxGroup wxGroup = wxGroupService.selectGroupByNoForCs(csId, wxAccount,groupNo );
        WxAccount account = wxAccountService.getWxAccountByAccountName(csId, wxAccount);
        if(wxGroup==null){
            Map<String, Object> rstMap = responseFailure("wxGroup不存在！");
            rstMap.putAll(map);
            return rstMap;
        }

        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("userWxId", memberWxId);
        reqMap.put("applyMsg", applyMsg);
        reqMap.put("groupWxId", wxGroup.getGroupno());

        WxCommand wxCommand = wxCommandService.generateCmdObject(csId,account.getId(),JSONUtils.toJSONString(reqMap),WxConstants.CmdTaskType.UNKNOWN, -1,WxConstants.CmdType.CRK_ADD_FRIEND, WxConstants.CmdPriority.UNKNOWN);
        commandProcessor.addCommand(csId,account.getId(),wxCommand);
        // 添加好友日志
        WxFriendLog wxFriendLog = new WxFriendLog();
        wxFriendLog.setCmdid(wxCommand.getId());
        wxFriendLog.setCmdstatus(wxCommand.getCmdstatus());
        wxFriendLog.setCmdtype(WxConstants.CmdType.CRK_ADD_FRIEND.getCode());
        wxFriendLog.setWxaccount(account.getWxid());
        wxFriendLog.setGroupid(wxGroup.getId());
        wxFriendLog.setGroupname(wxGroup.getGroupname());
        wxFriendLog.setFriendwxid(memberWxId);
        wxFriendLog.setFriendnick(memberNick);
        wxFriendLog.setAddtype(0);
        wxFriendLog.setRststatus(wxCommand.getRststatus());
        wxFriendLog.setApplymsg(applyMsg);
        wxFriendLog.setAddresult(0);
        wxFriendLog.setCsid(csId);
        wxFriendLog.setCreatetime(new Date());
        wxFriendLog.setUpdatetime(wxFriendLog.getCreatetime());
        wxFriendLogService.inserFriendLog(wxFriendLog);
        return null;
    }
}
